package com.huffman.smart_picture.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huffman.smart_picture.common.UserSession;
import com.huffman.smart_picture.common.exception.ErrorEnum;
import com.huffman.smart_picture.domain.constants.RedisConstant;
import com.huffman.smart_picture.domain.entity.FavoritePictureRecord;
import com.huffman.smart_picture.domain.enums.FavoriteEnum;
import com.huffman.smart_picture.domain.enums.LuaStatusEnum;
import com.huffman.smart_picture.domain.request.picture.PictureFavoriteRequest;
import com.huffman.smart_picture.mapper.FavoritePictureRecordMapper;
import com.huffman.smart_picture.service.FavoritePictureRecordService;
import com.huffman.smart_picture.utils.ThrowUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Optional;

/**
 * @author DengLin
 * @title 基于lua脚本实现点赞功能
 * @date 2025/5/11
 */
@Service("favoritePictureByLuaService")
public class FavoritePictureByLuaServiceImpl extends ServiceImpl<FavoritePictureRecordMapper, FavoritePictureRecord>
        implements FavoritePictureRecordService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean doFavoritePicture(PictureFavoriteRequest pictureFavoriteRequest, UserSession userSession) {
        ThrowUtil.throwIf(pictureFavoriteRequest == null || pictureFavoriteRequest.getId() == null,
                ErrorEnum.PARAM_EMPTY, "图片id为空");
        Long pictureId = pictureFavoriteRequest.getId();
        Long userId = userSession.getId();

        String timeSlice = getTimeSlice();
        String tempRecordKey = String.format(RedisConstant.TEMP_FAVORITE_PICTURE_RECORD_KEY, timeSlice);
        String userFavoriteKey = String.format(RedisConstant.TEMP_USER_RECORD_KEY, userId);
        Long result = redisTemplate.execute(
                RedisConstant.DO_FAVORITE_SCRIPT,
                Arrays.asList(tempRecordKey, userFavoriteKey),
                userId,
                pictureId
        );

        ThrowUtil.throwIf(LuaStatusEnum.FAIL.getStatus().equals(result), ErrorEnum.REQUEST_MANY, "用户已点赞");


        return LuaStatusEnum.SUCCESS.getStatus().equals(result);
    }

    @Override
    public boolean undoFavoritePicture(PictureFavoriteRequest pictureFavoriteRequest, UserSession userSession) {
        ThrowUtil.throwIf(pictureFavoriteRequest == null || pictureFavoriteRequest.getId() == null,
                ErrorEnum.PARAM_EMPTY, "图片id为空");
        Long pictureId = pictureFavoriteRequest.getId();
        Long userId = userSession.getId();

        String timeSlice = getTimeSlice();
        String tempRecordKey = String.format(RedisConstant.TEMP_FAVORITE_PICTURE_RECORD_KEY, timeSlice);
        String userFavoriteKey = String.format(RedisConstant.TEMP_USER_RECORD_KEY, userId);
        Long result = redisTemplate.execute(
                RedisConstant.UNDO_FAVORITE_SCRIPT,
                Arrays.asList(tempRecordKey, userFavoriteKey),
                userId,
                pictureId
        );

        ThrowUtil.throwIf(LuaStatusEnum.FAIL.getStatus().equals(result), ErrorEnum.REQUEST_MANY, "用户未点赞");


        return LuaStatusEnum.SUCCESS.getStatus().equals(result);
    }

    @Override
    public boolean haveFavoritePictureRecord(Long userId, Long pictureId) {
        // 先查redis
        String userFavoriteKey = String.format(RedisConstant.TEMP_USER_RECORD_KEY, userId);
        Integer favoriteType = (Integer) redisTemplate.opsForHash().get(userFavoriteKey, pictureId.toString());
        if (FavoriteEnum.getFavoriteEnum(favoriteType) != null) {
            return FavoriteEnum.DO.getStatus().equals(favoriteType);
        }
        // 缓存没中 查数据库
        FavoritePictureRecord record = getBaseMapper().getRecordByUserIdAndPicId(userId, pictureId);
        favoriteType = Optional.ofNullable(record)
                .map(FavoritePictureRecord::getStatus)
                .orElse(FavoriteEnum.UNDO.getStatus());

        // 写入缓存 todo 暂时不需要

        return FavoriteEnum.DO.getStatus().equals(favoriteType);
    }


    private String getTimeSlice() {
        DateTime nowDate = DateUtil.date();
        // 获取当前时间 最近的整数秒
        return DateUtil.format(nowDate, "HH:mm:") + (DateUtil.second(nowDate) / 10) * 10;
    }
}
